#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
4vs4战斗演示脚本
使用角色模板和技能模板创建角色，配置技能，并模拟战斗
"""

import json
import random
import uuid
from models.character_template import CharacterTemplateLibrary
from models.skill_template import SkillTemplateLibrary
from models.character import CharacterType
from models.battlefield import Battlefield
from game.battle_engine import BattleEngine
from utils.json_encoder import BattleJSONEncoder

def create_team_from_templates(team_name, character_type, templates_and_levels):
    """
    从模板创建队伍
    
    Args:
        team_name: 队伍名称
        character_type: 角色类型
        templates_and_levels: [(模板ID, 等级), ...]
    
    Returns:
        角色列表
    """
    team = []
    
    for i, (template_id, level) in enumerate(templates_and_levels):
        character_name = f"{team_name}_{i+1}"
        character_id = f"{team_name.lower()}_{template_id}_{str(uuid.uuid4())[:8]}"
        # 获取角色模板
        template = CharacterTemplateLibrary.get_template(template_id)
        character = CharacterTemplateLibrary.create_character_from_template(
            template_id, character_id, character_type, level
        )
        # 设置角色显示名称为模板名称
        character.name = template.name
        
        # 获取角色技能配置（从模板中获取）
        skills = []
        # 清空角色的技能列表，避免重复
        character.skills = []
        for skill_id in template.default_skills:
            try:
                # 使用正确的技能ID格式：基础技能ID
                skill = SkillTemplateLibrary.create_skill_from_template(skill_id, skill_id)
                skills.append(skill)
                # 将技能ID添加到角色的技能列表中（只添加一次）
                character.skills.append(skill_id)
            except (KeyError, ValueError):
                print(f"警告: 技能模板 '{skill_id}' 不存在，跳过")
                continue
        
        team.append(character)
        print(f"创建角色: {character.name} (模板: {template_id}, 等级: {level})")
        print(f"  属性: HP={character.current_hp}, ATK={character.attack}, DEF={character.defense}, SPD={character.speed}")
        print(f"  技能: {[skill.name for skill in skills]}")
        print()
        
        # 将技能信息存储到角色对象中（用于后续JSON生成）
        character._skills = skills
    
    return team



def generate_random_positions(team_size, y_range, battlefield_width=4):
    """
    为队伍生成随机站位
    
    Args:
        team_size: 队伍大小
        y_range: Y坐标范围 (min_y, max_y)
        battlefield_width: 战场宽度
    
    Returns:
        位置列表 [(x, y), ...]
    """
    min_y, max_y = y_range
    available_positions = [(x, y) for x in range(battlefield_width) for y in range(min_y, max_y + 1)]
    
    # 随机选择不重复的位置
    selected_positions = random.sample(available_positions, min(team_size, len(available_positions)))
    return selected_positions

def setup_battlefield_positions(team1, team2):
    """
    设置战场位置 - 随机生成站位
    
    Args:
        team1: 队伍1 (玩家队伍)
        team2: 队伍2 (敌方队伍)
    
    Returns:
        战场对象和位置信息
    """
    battlefield = Battlefield()  # 使用默认4x6的战场
    
    # 为玩家队伍生成随机位置 (下方区域 y=3,4,5)
    team1_positions = generate_random_positions(len(team1), (3, 5), battlefield.width)
    
    # 为敌方队伍生成随机位置 (上方区域 y=0,1,2)
    team2_positions = generate_random_positions(len(team2), (0, 2), battlefield.width)
    
    print(f"随机生成的玩家队伍位置: {team1_positions}")
    print(f"随机生成的敌方队伍位置: {team2_positions}")
    
    # 放置队伍1 (玩家)
    for i, character in enumerate(team1):
        if i < len(team1_positions):
            x, y = team1_positions[i]
            battlefield.place_character(character, x, y)
    
    # 放置队伍2 (敌方)
    for i, character in enumerate(team2):
        if i < len(team2_positions):
            x, y = team2_positions[i]
            battlefield.place_character(character, x, y)
    
    return battlefield, team1_positions, team2_positions

def format_battle_action(action, characters_dict):
    """
    格式化战斗行动为文字描述
    
    Args:
        action: 行动数据
        characters_dict: 角色ID到角色对象的映射
    
    Returns:
        格式化的文字描述
    """
    character = characters_dict.get(action["character_id"])
    if not character:
        return f"未知角色 {action['character_id']} 执行了行动"
    
    # 获取技能名称
    skill_id = action["skill_id"]
    try:
        from models.skill_template import SkillTemplateLibrary
        skill_template = SkillTemplateLibrary.get_template(skill_id)
        skill_name = skill_template.name
    except:
        skill_name = skill_id
    
    # 构建行动描述
    action_text = f"🎯 {character.name} 使用 [{skill_name}]"
    
    # 添加目标和效果信息
    if "effects" in action and action["effects"]:
        effects_text = []
        for effect in action["effects"]:
            target = characters_dict.get(effect["target_id"])
            target_name = target.name if target else effect["target_id"]
            
            if effect["effect_type"] == "damage":
                damage_text = f"对 {target_name} 造成 {effect['value']} 点伤害"
                if effect.get("is_crit"):
                    damage_text += " (暴击!)"
                if effect.get("is_dodged"):
                    damage_text += " (被闪避)"
                elif not effect.get("is_hit"):
                    damage_text += " (未命中)"
                effects_text.append(damage_text)
            elif effect["effect_type"] == "heal":
                effects_text.append(f"为 {target_name} 恢复 {effect['value']} 点生命值")
            elif effect["effect_type"] == "buff":
                effects_text.append(f"为 {target_name} 施加增益效果")
            elif effect["effect_type"] == "debuff":
                effects_text.append(f"为 {target_name} 施加减益效果")
        
        if effects_text:
            action_text += "，" + "，".join(effects_text)
    
    return action_text

def main(verbose_battle=False):
    """
    主函数：创建4vs4战斗并生成JSON结果
    
    Args:
        verbose_battle: 是否输出详细的战斗过程文字描述
    """
    print("=== 4vs4战斗演示 ===")
    print()
    
    # 创建玩家队伍 (4个角色)
    print("创建玩家队伍...")
    player_templates = [
        ("warrior_basic", 5),      # 战士
        ("mage_elemental", 4),     # 法师
        ("archer_ranger", 4),      # 弓箭手
        ("healer_priest", 3)       # 治疗师
    ]
    
    player_team = create_team_from_templates(
        "Player", CharacterType.PLAYER, player_templates
    )
    
    # 创建敌方队伍 (4个角色)
    print("创建敌方队伍...")
    enemy_templates = [
        ("berserker_fury", 5),     # 狂战士
        ("necromancer_dark", 4),   # 死灵法师
        ("assassin_shadow", 4),    # 刺客
        ("tank_heavy", 4)          # 坦克
    ]
    
    enemy_team = create_team_from_templates(
        "Enemy", CharacterType.ENEMY, enemy_templates
    )
    
    # 设置战场
    print("设置战场位置...")
    battlefield, player_positions, enemy_positions = setup_battlefield_positions(player_team, enemy_team)
    
    # 显示战场布局
    print("战场布局:")
    print(f"战场大小: {battlefield.width}x{battlefield.height}")
    print(f"玩家队伍位置: {len(battlefield.player_positions)}个角色")
    print(f"敌方队伍位置: {len(battlefield.enemy_positions)}个角色")
    print()
    
    # 创建战斗引擎并开始战斗
    print("开始4vs4战斗...")
    battle_engine = BattleEngine()
    
    # 创建战斗
    battle = battle_engine.create_battle("4v4_demo_battle")
    
    # 设置角色 - 使用随机生成的位置
    player_setup = [{"character": char, "x": pos[0], "y": pos[1]} 
                    for char, pos in zip(player_team, player_positions)]
    enemy_setup = [{"character": char, "x": pos[0], "y": pos[1]} 
                   for char, pos in zip(enemy_team, enemy_positions)]
    
    battle_engine.setup_characters(player_setup, enemy_setup)
    battle_engine.start_battle()
    
    # 创建角色字典用于详细输出
    all_characters = {}
    for char in player_team + enemy_team:
        all_characters[char.id] = char
    
    # 模拟战斗 - 自动执行多个回合直到战斗结束
    battle_results = []
    max_rounds = 20  # 最大回合数限制
    
    for round_num in range(1, max_rounds + 1):
        if verbose_battle:
            print(f"\n{'='*60}")
            print(f"⚔️  第 {round_num} 回合开始")
            print(f"{'='*60}")
        else:
            print(f"执行第 {round_num} 回合...")
        
        result = battle_engine.auto_battle_round()
        
        if result["success"]:
            battle_round_data = {
                "success": True,
                "round_number": result["round_number"],
                "actions": result["actions"],
                "battle_ended": result["battle_ended"]
            }
            
            # 详细战斗过程输出
            if verbose_battle and "actions" in result:
                print(f"\n📋 回合 {result['round_number']} 行动序列:")
                for i, action in enumerate(result["actions"], 1):
                    action_desc = format_battle_action(action, all_characters)
                    print(f"  {i}. {action_desc}")
                
                # 显示被动技能效果
                if "passive_effects" in result and result["passive_effects"]:
                    print(f"\n✨ 被动技能效果:")
                    for effect in result["passive_effects"]:
                        # 处理不同的被动效果数据结构
                        if "target_id" in effect:
                            target = all_characters.get(effect["target_id"])
                            target_name = target.name if target else effect["target_id"]
                        elif "character_id" in effect:
                            target = all_characters.get(effect["character_id"])
                            target_name = target.name if target else effect["character_id"]
                        else:
                            target_name = "未知目标"
                        
                        effect_type = effect.get("effect_type", "未知效果")
                        effect_value = effect.get("value", 0)
                        
                        if effect_type == "heal":
                            print(f"  💚 {target_name} 通过被动技能恢复 {effect_value} 点生命值")
                        else:
                            print(f"  ⭐ {target_name} 受到被动效果: {effect_type} (值: {effect_value})")
                
                # 显示回合结束时的角色状态
                if verbose_battle:
                    print(f"\n📊 回合结束状态:")
                    alive_players = [char for char in player_team if char.is_alive]
                    alive_enemies = [char for char in enemy_team if char.is_alive]
                    print(f"  🔵 玩家队伍: {len(alive_players)}/{len(player_team)} 存活")
                    print(f"  🔴 敌方队伍: {len(alive_enemies)}/{len(enemy_team)} 存活")
            
            # 添加被动技能效果信息
            if "passive_effects" in result and result["passive_effects"]:
                battle_round_data["passive_effects"] = result["passive_effects"]
            
            # 添加回合结束统计信息
            if "round_end_stats" in result:
                battle_round_data["round_end_stats"] = result["round_end_stats"]
            
            battle_results.append(battle_round_data)
        else:
            battle_results.append(result)
        
        if not result["success"]:
            print(f"战斗错误: {result.get('error', '未知错误')}")
            break
            
        if result.get("battle_ended", False):
            winner = result.get("winner", "未知")
            print(f"战斗结束！获胜方: {winner}")
            print(f"总共进行了 {round_num} 回合")
            break
    else:
        print(f"战斗达到最大回合数 {max_rounds}，强制结束")
    
    # 生成战斗JSON结果
    battle_json = {
        "battle_type": "4vs4",
        "battle_id": "4v4_demo_battle",
        "teams": {
            "player_team": [
                {
                    "id": char.id,
                    "name": char.name,
                    "template": player_templates[i][0],
                    "level": player_templates[i][1],
                    "initial_stats": {
                        "hp": char.max_hp,
                        "attack": char.attack,
                        "defense": char.defense,
                        "speed": char.speed,
                        "hit_rate": char.hit_rate,
                        "dodge_rate": char.dodge_rate,
                        "crit_rate": char.crit_rate,
                        "crit_damage": char.crit_damage
                    },
                    "final_stats": {
                        "current_hp": char.current_hp,
                        "is_alive": char.is_alive
                    },
                    "skills": [
                        {
                            "skill_id": skill_id,
                            "name": SkillTemplateLibrary.get_template(skill_id).name if skill_id in SkillTemplateLibrary.get_all_templates() else skill_id
                        }
                        for skill_id in char.skills
                    ],
                    "position": {"x": char.position_x, "y": char.position_y}
                }
                for i, char in enumerate(player_team)
            ],
            "enemy_team": [
                {
                    "id": char.id,
                    "name": char.name,
                    "template": enemy_templates[i][0],
                    "level": enemy_templates[i][1],
                    "initial_stats": {
                        "hp": char.max_hp,
                        "attack": char.attack,
                        "defense": char.defense,
                        "speed": char.speed,
                        "hit_rate": char.hit_rate,
                        "dodge_rate": char.dodge_rate,
                        "crit_rate": char.crit_rate,
                        "crit_damage": char.crit_damage
                    },
                    "final_stats": {
                        "current_hp": char.current_hp,
                        "is_alive": char.is_alive
                    },
                    "skills": [
                        {
                            "skill_id": skill_id,
                            "name": SkillTemplateLibrary.get_template(skill_id).name if skill_id in SkillTemplateLibrary.get_all_templates() else skill_id
                        }
                        for skill_id in char.skills
                    ],
                    "position": {"x": char.position_x, "y": char.position_y}
                }
                for i, char in enumerate(enemy_team)
            ]
        },
        "battlefield": battle.battlefield.to_dict(),
        "battle_results": battle_results,
        "summary": {
            "total_rounds": len([r for r in battle_results if r.get("success", False)]),
            "winner": battle_results[-1].get("winner") if battle_results and battle_results[-1].get("battle_ended") else None,
            "battle_ended": any(r.get("battle_ended", False) for r in battle_results)
        }
    }
    
    # 保存战斗结果到JSON文件
    filename = "battle_4v4_result.json"
    with open(filename, 'w', encoding='utf-8') as f:
        json.dump(battle_json, f, ensure_ascii=False, indent=2, cls=BattleJSONEncoder)
    
    print(f"战斗结果已保存到: {filename}")
    print()
    
    # 显示战斗总结
    print("\n" + "="*50)
    print("战斗总结")
    print("="*50)
    
    if battle_results and battle_results[-1].get("battle_ended"):
        winner = battle_results[-1].get("winner")
        if winner == "player":
            print("🎉 玩家队伍获胜！")
        elif winner == "enemy":
            print("💀 敌方队伍获胜！")
        else:
            print("⚖️ 战斗平局！")
    else:
        print("⏰ 战斗未分胜负（达到最大回合数）")
    
    print(f"\n战斗回合数: {len(battle_results)}")
    
    # 统计被动技能效果
    total_passive_effects = 0
    passive_heal_total = 0
    for round_data in battle_results:
        if "passive_effects" in round_data:
            effects = round_data["passive_effects"]
            total_passive_effects += len(effects)
            for effect in effects:
                if effect["effect_type"] == "heal":
                    passive_heal_total += effect["value"]
    
    if total_passive_effects > 0:
        print(f"\n🔮 被动技能统计:")
        print(f"  - 总计触发次数: {total_passive_effects}")
        print(f"  - 被动治疗总量: {passive_heal_total}")
    
    # 显示存活角色信息
    print("\n📊 队伍状态:")
    
    # 玩家队伍
    alive_players = [char for char in player_team if char.is_alive]
    print(f"\n🔵 玩家队伍: {len(alive_players)}/{len(player_team)} 存活")
    for char in player_team:
        status = "✅ 存活" if char.is_alive else "💀 阵亡"
        position = f"({char.position_x}, {char.position_y})"
        hp_percentage = round((char.current_hp / char.max_hp) * 100, 1) if char.max_hp > 0 else 0
        cooldowns = ", ".join([f"{skill}({cd})" for skill, cd in char.skill_cooldowns.items()]) if char.skill_cooldowns else "无"
        print(f"  - {char.name} {status} - HP: {char.current_hp}/{char.max_hp} ({hp_percentage}%) - 位置: {position}")
        if char.skill_cooldowns:
            print(f"    冷却中技能: {cooldowns}")
    
    # 敌方队伍
    alive_enemies = [char for char in enemy_team if char.is_alive]
    print(f"\n🔴 敌方队伍: {len(alive_enemies)}/{len(enemy_team)} 存活")
    for char in enemy_team:
        status = "✅ 存活" if char.is_alive else "💀 阵亡"
        position = f"({char.position_x}, {char.position_y})"
        hp_percentage = round((char.current_hp / char.max_hp) * 100, 1) if char.max_hp > 0 else 0
        cooldowns = ", ".join([f"{skill}({cd})" for skill, cd in char.skill_cooldowns.items()]) if char.skill_cooldowns else "无"
        print(f"  - {char.name} {status} - HP: {char.current_hp}/{char.max_hp} ({hp_percentage}%) - 位置: {position}")
        if char.skill_cooldowns:
            print(f"    冷却中技能: {cooldowns}")
    
    print()
    print("4vs4战斗演示完成！")
    return filename

if __name__ == "__main__":
    import sys
    
    # 检查命令行参数
    verbose_battle = False
    if len(sys.argv) > 1 and sys.argv[1].lower() in ['--verbose', '-v', '--detail', '-d']:
        verbose_battle = True
        print("🔍 启用详细战斗过程输出模式")
        print("提示: 使用 'python battle_4v4_demo.py --verbose' 或 'python battle_4v4_demo.py -v' 启用此模式")
        print()
    
    main(verbose_battle)